from copy import deepcopy

from app.settings import BASE_DIR
from utils import execute_cmd_chains, write_to_json, read_from_json
from . import command

ca_config_module = read_from_json("{}/cert/module/ca-config.json".format(BASE_DIR))
ca_csr_module = read_from_json("{}/cert/module/ca-csr.json".format(BASE_DIR))
cert_csr_module = read_from_json("{}/cert/module/cert-csr.json".format(BASE_DIR))


# 配置文件生成------------------------------------------------------------------------------------------------

def gen_ca_config(out_dir, profiles):
    ca_config = deepcopy(ca_config_module)

    for profile in profiles:
        profile_name = profile.pop("profile")
        profile_expiry_str = "{}h".format(profile["expiry"]) if profile["expiry"] else "262800h"
        profile["expiry"] = profile_expiry_str
        ca_config["signing"]["profiles"][profile_name] = profile

    path = out_dir + "/ca-config.json"
    write_to_json(path, ca_config)
    return path


def gen_ca_csr_config(out_dir, CN, expiry):
    ca_csr = deepcopy(ca_csr_module)

    expiry_str = "{}h".format(expiry) if expiry else "262800h"
    ca_csr["CA"]["expiry"] = expiry_str
    ca_csr["CN"] = CN

    path = out_dir + "/ca-csr.json"
    write_to_json(path, ca_csr)
    return path


def gen_cert_csr_config(out_dir, cert_configs):
    cert_csr = deepcopy(cert_csr_module)

    result = {}
    for config in cert_configs:
        name = config.pop("name")
        profile = config.pop("profile")
        cert_csr["CN"] = config["CN"]
        cert_csr["hosts"] = config["hosts"]
        cert_csr["names"][0]["O"] = config["O"]

        path = out_dir + "/{}-cert-csr.json".format(name)
        write_to_json(path, cert_csr)
        result[name] = (profile, path)

    return result


# 证书签发------------------------------------------------------------------------------------------------

def sign_ca(cert_dir, ca_csr_path):
    chains = command.cmd_gen_ca_cert(
        csr_config=ca_csr_path,
        cert_dir=cert_dir,
        cert_name="ca"
    )
    exec_result, stdout, stderr = execute_cmd_chains(chains)
    certs = ["ca.pem", "ca-key.pem", "ca.csr"]  # 公钥，私钥，csr

    return exec_result, stdout, stderr, ("{}/{}".format(cert_dir, f) for f in certs)


def sign_cert(ca_path, ca_key_path, ca_config_path, profile, cert_csr_config, cert_name, cert_dir):
    chains = command.cmd_gen_key_cert(
        ca_public=ca_path,
        ca_private=ca_key_path,
        ca_config=ca_config_path,
        profile=profile,
        csr_config=cert_csr_config,
        cert_name=cert_name,
        cert_dir=cert_dir,
    )
    exec_result, stdout, stderr = execute_cmd_chains(chains)
    certs = ["{}.pem".format(cert_name), "{}-key.pem".format(cert_name), "{}.csr".format(cert_name)]  # 公钥，私钥，csr
    return exec_result, stdout, stderr, ("{}/{}".format(cert_dir, f) for f in certs)


# 证书查询------------------------------------------------------------------------------------------------

def get_cert_info(cert_file):
    chains = command.cmd_get_cert_info(cert_file)
    exec_result, stdout, stderr = execute_cmd_chains(chains)

    return exec_result, stdout, stderr


# kube config生成---------------------------------------------------------------------------------------------

def gen_kube_config_by_cert(cluster, apiserver, user, context, kube_config_path, ca, cert, cert_key):
    chains = command.cmd_gen_kube_config(
        by="cert",
        cluster=cluster,
        apiserver=apiserver,
        conf=kube_config_path,
        user=user,
        context=context,
        ca=ca,
        cert=cert,
        cert_key=cert_key,
    )
    exec_result, stdout, stderr = execute_cmd_chains(chains)
    return exec_result, stdout, stderr


def gen_kube_config_by_token(cluster, apiserver, user, context, kube_config_path, ca, token):
    chains = command.cmd_gen_kube_config(
        by="token",
        cluster=cluster,
        apiserver=apiserver,
        conf=kube_config_path,
        user=user,
        context=context,
        ca=ca,
        token=token,
    )
    exec_result, stdout, stderr = execute_cmd_chains(chains)
    return exec_result, stdout, stderr


def set_default_context(kube_config_path, context):
    chains = command.cmd_set_default_context(kube_config_path, context)
    exec_result, stdout, stderr = execute_cmd_chains(chains)
    return exec_result, stdout, stderr
